package fr.sportcom.sportcom.controller;

import java.util.ArrayList;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.LocationSource;
import com.google.android.gms.maps.Projection;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import fr.sportcom.sportcom.R;
import fr.sportcom.sportcom.model.AdsManager;
import fr.sportcom.sportcom.model.CustomHttpClient;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

public class MapSponsorActivity extends FragmentActivity implements OnCameraChangeListener {

	private GoogleMap mMap;
	private LocationManager mLocationManager;
	private String mProviderName;
	private myLocationSource mLocationSourceListener = new myLocationSource();
	private ArrayList<Marker> lMarker = new ArrayList<Marker>();
	private RefreshMarkerTask mMarkTask = null;
	private boolean mPositionFound = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//setContentView(R.layout.activity_map_sponsor);
		setContentView(R.layout.sponso_layout);
		View appContent = LayoutInflater.from(this).inflate(
				R.layout.activity_map_sponsor, 
				(ViewGroup) this.findViewById(R.id.app_content), 
				false);
		((LinearLayout)this.findViewById(R.id.app_content)).addView(appContent);
		AdsManager.displayAds(this);

		// On renseigne les info.
		initGeoloc();
		initMap();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		return super.onOptionsItemSelected(item);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		AdsManager.displayAds(this);
	}

	private class myLocationSource implements LocationSource, LocationListener {

		private OnLocationChangedListener mListener;

		@Override
		public void activate(OnLocationChangedListener listener) {
			mListener = listener;
		}

		@Override
		public void deactivate() {
			mListener = null;
		}


		@Override
		public void onLocationChanged(Location location) {
			if (mListener != null) {
				mListener.onLocationChanged(location);
				if(!mPositionFound) {
					mPositionFound = true;
					mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
					if(mMarkTask == null) {
						mMarkTask = new RefreshMarkerTask();
						mMarkTask.execute(mMap.getProjection());
					}
				}
			}
		}

		@Override
		public void onProviderDisabled(String provider) {
			mLocationManager.removeUpdates(this);
		}

		@Override
		public void onProviderEnabled(String provider) {
			mLocationManager.requestLocationUpdates(mProviderName, 30000, 50, this);
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {}

	}

	private void initMap() {

		// Try to obtain the map from the SupportMapFragment.
		mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
		// Check if we were successful in obtaining the map.
		if (mMap != null) {
			/*MarkerOptions markOp = new MarkerOptions();
			markOp.position(selectedEvent.getLatLngLoc())
			.title("Ev�nement")
			.visible(true);
			mMap.addMarker(markOp);*/

			//mMap.moveCamera(CameraUpdateFactory.newLatLng(selectedEvent.getLatLngLoc()));


	        mMap.setLocationSource(mLocationSourceListener);
			mMap.setMyLocationEnabled(true);
			mMap.setOnCameraChangeListener(this);
		}
	}

	private void initGeoloc() {
		mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

		Criteria critere = new Criteria();
		// Pour indiquer la pr�cision voulue
		// On peut mettre ACCURACY_FINE pour une haute pr�cision ou ACCURACY_COARSE pour une moins bonne pr�cision
		critere.setAccuracy(Criteria.ACCURACY_FINE);
		// Est-ce que le fournisseur doit �tre capable de donner une altitude ?
		critere.setAltitudeRequired(false);
		// Est-ce que le fournisseur doit �tre capable de donner une direction ?
		critere.setBearingRequired(true);
		// Est-ce que le fournisseur peut �tre payant ?
		critere.setCostAllowed(false);
		// Pour indiquer la consommation d'�nergie demand�e
		// Criteria.POWER_HIGH pour une haute consommation, Criteria.POWER_MEDIUM pour une consommation moyenne et Criteria.POWER_LOW pour une basse consommation
		critere.setPowerRequirement(Criteria.POWER_HIGH);
		// Est-ce que le fournisseur doit �tre capable de donner une vitesse ?
		critere.setSpeedRequired(false);

		mProviderName = mLocationManager.getBestProvider(critere, true);
		mLocationManager.requestLocationUpdates(mProviderName, 30000, 50, mLocationSourceListener);
	}

	@Override
	public void onCameraChange(CameraPosition pos) {
		if(mMarkTask == null && mPositionFound) {
			mMarkTask = new RefreshMarkerTask();
			mMarkTask.execute(mMap.getProjection());
		}
	}
	
	private class RefreshMarkerTask extends AsyncTask<Projection, Void, Boolean> {
		
		JSONArray list;
		
		@Override
		protected Boolean doInBackground(Projection... params) {

			//Projection proj = params[0];
			LatLngBounds bounds = params[0].getVisibleRegion().latLngBounds;
			double minLat = bounds.southwest.latitude;
			double maxLat = bounds.northeast.latitude;
			double minLong = bounds.southwest.longitude;
			double maxLong = bounds.northeast.longitude;
			
			
			CustomHttpClient request = new CustomHttpClient();
			JSONObject jObj = null;
			ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
			param.add(new BasicNameValuePair("minLat", ""+minLat));
			param.add(new BasicNameValuePair("maxLat", ""+maxLat));
			param.add(new BasicNameValuePair("minLong", ""+minLong));
			param.add(new BasicNameValuePair("maxLong", ""+maxLong));

			try {
				jObj = request.postData("getSponsorsPosition", param);

				if(jObj.getInt("back") != 0) {
					return false;
				}
				
				list = jObj.getJSONArray("list");
				/*refMap.get().clear();
				lMarker.clear();
				for(int i=0; i<list.length(); i++) {
					MarkerOptions markOp = new MarkerOptions();
					markOp.position(new LatLng(list.getDouble(i), list.getDouble(i)))
					.title("Ev�nement")
					.visible(true);
					lMarker.add( refMap.get().addMarker(markOp) );
					//add(list.getString(i))
				}*/

			} catch (Exception e) {
				return false;
			}

			return true;
		}

		@Override
		protected void onPostExecute(final Boolean success) {
			mMarkTask = null;

			mMap.clear();
			lMarker.clear();
			
			// 2 : Zoom minimum | 21 : Zoom Maximum
			float currentZoom = mMap.getCameraPosition().zoom;
			
			try {
				for(int i=0; i<list.length(); i++) {
					String libelle = list.getJSONObject(i).getString("mag_libelle");
					String adresse = list.getJSONObject(i).getString("mag_adr");
					String ville = list.getJSONObject(i).getString("mag_ville");
					
					MarkerOptions markOp = new MarkerOptions();
					markOp.position(new LatLng(list.getJSONObject(i).getDouble("mag_latitude"), list.getJSONObject(i).getDouble("mag_longitude")))
					.title(libelle)
					.snippet(adresse + "\n" + list.getJSONObject(i).getInt("mag_cp") + " " + ville)
					.visible(list.getJSONObject(i).getInt("zoom_lvl") <= currentZoom);
					lMarker.add( mMap.addMarker(markOp) );
				}
			} catch (Exception e) {}
		}
	}
}
